package org.springblade.modules.platform.controller;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import org.springblade.modules.platform.dto.*;
import org.springblade.modules.platform.entity.*;
import org.springblade.modules.platform.props.HuatengProperties;
import org.springblade.modules.platform.service.*;
import org.springblade.modules.platform.utils.ModelUtils;
import org.springblade.modules.platform.vo.*;
import org.springblade.modules.platform.vo.enums.ProductTypeEnum;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springblade.core.log.annotation.ApiLog;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author SYG
 * @since 2022-08-30
 */

@RestController
@AllArgsConstructor
@RequestMapping("/service-huateng-sxdb/deviceTable")
@Api(value = "", tags = "设备列表接口")
public class DeviceTableController {
    private final IProductModelFunctionService iProductModelFunctionService;
    private final IDeviceTableService iDeviceTableService;
    private final IProductTypeService iProductTypeService;
    private final IEquipmentRuningStateService iEquipmentRuningStateService;
    private final IProductModelPropertiesService iProductModelPropertiesService;
    private final IEquipmentLogManagementService equipmentLogManagementService;
    private final HuatengProperties huatengProperties;
    private static RestTemplate restTemplate = new RestTemplate();
    @Autowired
    ModelUtils modelUtils;

    @GetMapping("/list")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "设备列表", notes = "传入deviceTablePageDTO")
    public R<DeviceTableListVO> list(DeviceTablePageDTO deviceTablePageDTO) {
        DeviceTableListVO deviceTableListVO = iDeviceTableService.selectDeviceList(deviceTablePageDTO);
        return R.data(deviceTableListVO);
    }


    @GetMapping(value = "/info/{deviceId}")
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "获取设备详细信息", notes = "传入deviceId")
    public  R<DeviceTableVO> getInfo(@PathVariable("deviceId") String deviceId) {
        DeviceTableVO deviceTableVO = iDeviceTableService.selectDeviceById(deviceId);
        return R.data(deviceTableVO);
    }


    @PostMapping(value = "/install")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "新增设备", notes = "传入deviceTableDTO")
    public R add(@RequestBody DeviceTableDTO deviceTableDTO){
        DeviceTableVO deviceTableVO = iDeviceTableService.selectDeviceById(deviceTableDTO.getDeviceId());
        if(deviceTableVO!=null){
            return R.fail("设备编号重复!");
        }
        iDeviceTableService.insertDevice(deviceTableDTO);
        return R.success("成功");
    }



    @PutMapping(value = "/update")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "修改设备", notes = "传入deviceTableDTO")
    public R edit(@RequestBody DeviceTableDTO deviceTableDTO) {
        iDeviceTableService.updateDevice(deviceTableDTO);
        return R.success("成功");
    }


    @DeleteMapping("/remove/{deviceIds}")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "删除设备", notes = "传入deviceIds")
    public R remove(@PathVariable String[] deviceIds){
        iDeviceTableService.removeDevice(deviceIds);
        return R.success("成功");
    }



    @PutMapping(value = "/updateStatus")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "启用/禁用", notes = "传入updateDeviceStatusDTO")
    public R updateStatus(@RequestBody UpdateDeviceStatusDTO updateDeviceStatusDTO) {
        iDeviceTableService.updateStatus(updateDeviceStatusDTO);
        return R.success("成功");
    }
    @ApiLog("产品列表")
    @GetMapping("/productTypeList")
    @ApiOperationSupport(order = 12)
    @ApiOperation(value = "产品列表", notes = "传入productType")
    public R<List<ProductType>> productTypeList() {
        List<ProductType> list = iProductTypeService.list(new QueryWrapper<ProductType>().lambda()
                .eq(ProductType::getIsDeleted, 0)
                .eq(ProductType::getState, 1));
        return R.data(list);
    }

    @ApiLog("设备详情-设备运行状态")
    @GetMapping("/equipmentRuningStateList")
    @ApiOperationSupport(order = 11)
    @ApiOperation(value = "设备详情-设备运行状态", notes = "equipmentId")
    public R<List<EquipmentRuningStateVO>> equipmentRuningState(String equipmentId) {
        List<EquipmentRuningStateVO> equipmentRuningStateVOS = iDeviceTableService.equipmentRuningState(equipmentId);
        return R.data(equipmentRuningStateVOS);
    }
    @ApiLog("设备管理-设备详情-设备运行状态-详情分页")
    @GetMapping("/equipmentRuningStatePage")
    @ApiOperationSupport(order = 11)
    @ApiOperation(value = "设备详情-设备运行状态-详情分页", notes = "equipmentId")
    public R<EquipmentRuningStateListVO> equipmentRuningStatePage(EquipmentRuningStateList equipmentRuningStateList, Query query) {
        DeviceTableVO deviceTableVO = iDeviceTableService.selectDeviceById(equipmentRuningStateList.getEquipmentId());

        ProductType one1 = iProductTypeService.getOne(new QueryWrapper<ProductType>().lambda()
                .eq(ProductType::getProductId, deviceTableVO.getProductId())
                .eq(ProductType::getIsDeleted, 0)
                .eq(ProductType::getState, 1));

        EquipmentRuningStatePageListDTO equipmentRuningStatePageListDTO = new EquipmentRuningStatePageListDTO();
        BeanUtils.copyProperties(equipmentRuningStateList,equipmentRuningStatePageListDTO);
        equipmentRuningStatePageListDTO.setCurrent(query.getCurrent());
        equipmentRuningStatePageListDTO.setSize(query.getSize());
        EquipmentRuningStateListVO equipmentRuningStateListVO = iEquipmentRuningStateService.selectEquipmentRuningStateListVOByPage(equipmentRuningStatePageListDTO);
        Map<String,String> tableHeader = new HashMap<>();
        equipmentRuningStateListVO.setIsGateway(one1.getEquipmentType());
            if(one1.getEquipmentType()!=3){
            ProductModelProperties one = iProductModelPropertiesService.getOne(new QueryWrapper<ProductModelProperties>().lambda().eq(ProductModelProperties::getProductId, deviceTableVO.getProductId()));
            tableHeader = modelUtils.modelParsing(one.getPropertiesJson(),equipmentRuningStateList.getPropertieId());
            tableHeader.put("insertTime","时间");
        }
        equipmentRuningStateListVO.setTableHeader(tableHeader);
        return R.data(equipmentRuningStateListVO);
    }


    /**
     * 自定义分页
     */
    @ApiLog("设备管理-设备功能-参数")
    @GetMapping("/productModelFunctionSonList_v2")
    @ApiOperationSupport(order = 22)
    @ApiOperation(value = "设备详情-设备功能-参数", notes = "传入KEY")
    public R<List<Map<String,Object>>> productModelFunctionSonList(String equipmentId,String productId,String key) {
        ProductModelFunction one = iProductModelFunctionService.getOne(new QueryWrapper<ProductModelFunction>()
                .lambda().eq(ProductModelFunction::getProductId, productId));
        String functionJson = one.getFunctionJson();
        JSONArray jsonArray = JSONObject.parseArray(functionJson);
        List<Map<String,Object>>  list1 = new ArrayList<>();
        for (Object o : jsonArray) {
            JSONObject o1 = (JSONObject) o;
            String id = o1.get("id").toString();
            if(id.equalsIgnoreCase(key)){
                JSONArray inputs = (JSONArray)o1.get("inputs");
                Map<String,Object> functionsVO = new HashMap<>();
                for (Object input : inputs) {
                    JSONObject o2 = (JSONObject) input;
                    String valueType = o2.get("valueType").toString();
                    JSONObject jsonObject = JSONObject.parseObject(valueType);
                    if(jsonObject.containsKey("type")){
                        String type = jsonObject.get("type").toString();
                        if(type.equals("object")){
                            String parameters = jsonObject.get("parameters").toString();
                            Map<String, Object> map = v1(parameters);
                            functionsVO.put(o2.get("id").toString(),map);
                        }else {
                            functionsVO.put(o2.get("id").toString(),o2.get("name").toString());
                        }
                    }else {
                        functionsVO.put(o2.get("id").toString(),o2.get("name").toString());
                    }
                }
                list1.add(functionsVO);
            }
        }
        return R.data(list1);
    }

    private static Map<String,Object> v1 (String parameters){
        JSONArray jsonArray = JSONArray.parseArray(parameters);
        Map<String,Object> map = new HashMap<>();
        for(Object o : jsonArray){
            JSONObject o1 = (JSONObject) o;
            String id = o1.get("id").toString();
            String name = o1.get("name").toString();
            String valueType = o1.get("valueType").toString();
            JSONObject jsonObject = JSONObject.parseObject(valueType);
            String type = jsonObject.get("type").toString();
            if(type.equals("object")){
                String parameters1 = jsonObject.get("parameters").toString();
                Map<String,Object> v = v1(parameters1);
                map.put(id,v);
            }
            map.put(id,name);
        }
        return map;
    }



    @ApiLog("产品物模型-获取功能下拉框")
    @GetMapping("/alarm/productModelFunctionlist")
    @ApiOperationSupport(order = 21)
    @ApiOperation(value = "产品物模型-获取功能下拉框", notes = "")
    public R<Map<String,String>> productModelFunctionServicelist(String productId) {
        Map<String,String> map = new HashMap<>();
        ProductModelFunction one = iProductModelFunctionService.getOne(new QueryWrapper<ProductModelFunction>().lambda()
                .eq(ProductModelFunction::getProductId, productId));
        if(one==null|| StringUtils.isEmpty(one.getFunctionJson())){
            return R.data(map);
        }
        String functionJson = one.getFunctionJson();
        JSONArray objects = JSONObject.parseArray(functionJson);
        for(Object o:objects){
            JSONObject o1 = (JSONObject) o;
            String id = o1.get("id").toString();
            String name = o1.get("name").toString();
            map.put(id,name);
        }
        return R.data(map);
    }
    /**
     *
     */
    @ApiLog("设备管理-设备功能-执行")
    @PostMapping("/equipmentFunction")
    @ApiOperationSupport(order = 23)
    @ApiOperation(value = "设备管理-设备功能-执行", notes = "传入productType")
    public R updateAlarmState(@RequestBody EquipmentFunctionDTO equipmentFunctionDTO) {

        String funId = equipmentFunctionDTO.getFunId();
        String equipmentId = equipmentFunctionDTO.getEquipmentId();
        DeviceTableVO deviceTableVO = iDeviceTableService.selectDeviceById(equipmentId);
        if(funId.equalsIgnoreCase("deviceControl")){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("measuringPlatformCode",deviceTableVO.getAffiliatedInstitutionsCode());

            List<JSONObject> jsonObjects = new ArrayList<>();
            JSONObject jsonObject1 = new JSONObject();
            jsonObject1.put("deviceId",deviceTableVO.getAffiliatedInstitutionsCode());
            jsonObject1.put("type", ProductTypeEnum.getEnum(deviceTableVO.getProductId()).getMsg());
            jsonObjects.add(jsonObject1);
            jsonObject.put("list",jsonObjects);
            HttpEntity<JSONObject> httpEntity = new HttpEntity<>(jsonObject,new HttpHeaders());
            ResponseEntity<String> exchange = restTemplate.exchange(huatengProperties.getReadDeviceData(), HttpMethod.POST, httpEntity, String.class);
            if(exchange.getStatusCodeValue()==200){
                String body = exchange.getBody();
                JSONObject jsonObject2 = JSONObject.parseObject(body);
                JSONObject data = (JSONObject)jsonObject2.get("data");
                JSONArray deviceList = (JSONArray) data.get("deviceList");
                if(CollectionUtils.isEmpty(deviceList)){
                    return R.data(true);
                }
                JSONObject o = (JSONObject)deviceList.get(0);
                JSONArray attributeListDTO = (JSONArray)o.get("attributeListDTO");
                if(CollectionUtils.isEmpty(attributeListDTO)){
                    return R.data(true);
                }
                attributeListDTO.forEach(x->{
                    JSONObject l =(JSONObject) x;
                    EquipmentRuningState equipmentRuningState1 = new EquipmentRuningState();
                    equipmentRuningState1.setEquipmentId(deviceTableVO.getDeviceId());
                    equipmentRuningState1.setInsertTime(System.currentTimeMillis());
                    equipmentRuningState1.setUpdateTime(System.currentTimeMillis());
                    equipmentRuningState1.setPropertieId(l.get("key").toString());
                    Map<String, Object> map = new HashMap<>();
                    map.put(l.get("key").toString(), l.get("value").toString());
                    equipmentRuningState1.setJsonText(JSONObject.toJSONString(map));
                    iEquipmentRuningStateService.remove(Wrappers.<EquipmentRuningState>query().lambda().eq(EquipmentRuningState::getEquipmentId, deviceTableVO.getDeviceId()).eq(EquipmentRuningState::getPropertieId, l.get("key").toString()));
                    iEquipmentRuningStateService.save(equipmentRuningState1);
                });
            }
        }else {
            String msg = equipmentFunctionDTO.getMsg();
            JSONObject o = (JSONObject)JSONArray.parseArray(msg).get(0);
            Integer type = Integer.valueOf(o.get("type").toString());
            String s = huatengProperties.getStartMeasurement() + equipmentFunctionDTO.getEquipmentId() + "&type=" +type;
            restTemplate.getForObject(s,  String.class);
        }
        return R.status(true);
    }

    @GetMapping("/equipmentLogManagementPage")
    @ApiOperationSupport(order = 9)
    @ApiOperation(value = "设备详情-日志管理-分页", notes = "传入productId")
    public R<EquipmentLogManagementPageVO> equipmentLogManagementPage(EquipmentLogManagementPageDTO equipmentLogManagementPageDTO) {
        EquipmentLogManagementPageVO equipmentLogManagementPageVO = equipmentLogManagementService.selectEquipmentLogManagementByPage(equipmentLogManagementPageDTO);
        return R.data(equipmentLogManagementPageVO);
    }
}

